package com.zzt.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zzt.dao.GwcMapper;
import com.zzt.dao.MyorderMapper;
import com.zzt.dao.ShopsMapper;
import com.zzt.entity.*;
import com.zzt.util.RedisUtils;
import io.lettuce.core.RedisCommandExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MyorderServiceImpl implements MyorderService{

    @Resource
    MyorderMapper myorderMapper;
    @Resource
    ShopsMapper shopsMapper;
    @Resource
    GwcMapper gwcMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Resource
    RedisUtils redisUtils;

    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public Myorder createOrder(Myorder myorder) throws JsonProcessingException {
        //redis锁
        //使用这个方法并实现接口是因为普通的 事务会报错，具体原理我转载了一篇博客
        redisTemplate.execute(new SessionCallback<List<Object>>() {
            @Override
            public <K, V> List<Object> execute(RedisOperations<K, V> operations) throws DataAccessException, RedisCommandExecutionException {
                redisUtils.set("order",myorder.getTotalprice(),10);
                operations.watch((K) "order");
                operations.multi();
                //执行
                int insert = myorderMapper.insertSelective(myorder);

                //先查一下购物车东西 
                List<Gwc> gwcs = gwcMapper.selectAllByMno(myorder.getMno());
                if(gwcs.isEmpty()){
                    operations.discard();   //防止支付完后回退页面继续支付
                }

                List<Shops> shopss = new ArrayList<Shops>();
                //再用oid和购物车的东西一起加入到shops表中
                for (Gwc gwc : gwcs) {
                    Shops shops = new Shops(myorder.getOid(),gwc.getGname(),gwc.getNum());
                    shopss.add(shops);
                    shopsMapper.insertSelective(shops);
                    //最后要把购物车清空
                    gwcMapper.deleteByPrimaryKey(gwc.getGwcid());
                }
                //把购物车商品也加到订单实体类中
//        myorder.setShops(shopss);
                System.out.println(myorder);

                operations.unwatch();
                return operations.exec();
            }
        });

//        redisTemplate.watch("order");   //监视
//        redisTemplate.multi();                  //事务

        //插入到myorder表中   再获取oid 将具体商品插入到shops中


//        redisTemplate.exec();
//        redisTemplate.unwatch();

        return myorder;
    }

    @Override
    public List<Myorder> showAllOrders(int mno) {
        //先查订单表
        MyorderExample myorderExample = new MyorderExample();
        MyorderExample.Criteria criteria1 = myorderExample.createCriteria();
        criteria1.andMnoEqualTo(mno);
        List<Myorder> myorders = null;
        try {
            myorders = myorderMapper.selectByExample(myorderExample);
        } catch (Exception exception) {

        }


        //再根据订单表查每个订单对应的商品
        for (Myorder myorder : myorders) {
            ShopsExample shopsExample = new ShopsExample();
            ShopsExample.Criteria criteria2 = shopsExample.createCriteria();
            criteria2.andOidEqualTo(myorder.getOid());
            List<Shops> shops = shopsMapper.selectByExample(shopsExample);
            //把商品名称放入order里面的shopNames和shopNums数组中
            String[] shopNames = new String[shops.size()];
            Integer[] shopNums = new Integer[shops.size()];
            int i=0;
            for (Shops shop : shops) {
                shopNames[i] = shop.getGname();
                shopNums[i] = shop.getNum();
                i++;
            }
            myorder.setShopNames(shopNames);
            myorder.setShopNums(shopNums);
        }
        System.out.println("myorders2= "+myorders);

        return myorders;
    }
}
